﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using System.Collections;
using System.Globalization;
using System.IO;

namespace Localiser
{
    internal class ResxTranslator
    {
        private readonly string _translationFolder;
        private readonly string _translationFilePrefix;

        public string TranslationFolder
        {
            get
            {
                return _translationFolder;
            }
        }

        private string GetFileName(CultureInfo cultureInfo)
        {
            return Path.Combine(_translationFolder,
                                string.Format("{0}_{1}.txt", _translationFilePrefix, cultureInfo.Name));
        }

        public CultureInfo[] GetAvailableTranslations()
        {
            string[] files = Directory.GetFiles(_translationFolder, string.Format("{0}_*.txt", _translationFilePrefix));

            List<CultureInfo> result = new List<CultureInfo>();
            foreach (string file in files)
            {
                string cultureName = Path.GetFileName(file).Substring(_translationFilePrefix.Length + 1, 5);
                CultureInfo culture = new CultureInfo(cultureName);
                result.Add(culture);
            }

            return result.ToArray();
        }

        private Dictionary<string, string> ReadTranslationFile(CultureInfo cultureInfo)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            using (StreamReader reader = new StreamReader(GetFileName(cultureInfo)))
            {
                string english;

                while ((english = reader.ReadLine()) != null)
                {
                    string translation = reader.ReadLine();

                    if (translation != null)
                    {
                        if (!result.ContainsKey(english))
                        {
                            result.Add(english, translation);
                        }
                    }
                }

                reader.Close();
            }

            return result;
        }

        private static string Translate(IDictionary<string, string> translation, string text)
        {
            if (translation.ContainsKey(text))
            {
                return translation[text];
            }
            else if (text.Contains(Environment.NewLine))
            {
                string[] lines = text.Split(new char[] { '\r', '\n' });
                StringBuilder sb = new StringBuilder();
                foreach (string line in lines)
                {
                    string result = Translate(translation, line);

                    if (result != null)
                    {
                        sb.AppendLine(result);
                    }
                    else
                    {
                        sb.AppendLine(line);
                    }
                }

                return sb.ToString();
            }
            else
            {
                return text;
            }
        }

        public ResxTranslator(string translationFolder, string translationFilePrefix)
        {
            _translationFolder = translationFolder;
            _translationFilePrefix = translationFilePrefix;
        }

        public void GenerateTranslatedResource(string sourceFile, string destFile, CultureInfo destinationCulture)
        {
            Dictionary<string, string> destTranslation = ReadTranslationFile(destinationCulture);

            ResXResourceReader resourceReader = new ResXResourceReader(sourceFile);
            try
            {
                ResXResourceWriter writer = new ResXResourceWriter(destFile);

                try
                {
                    IDictionaryEnumerator enumerator = resourceReader.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        string key = enumerator.Key.ToString();
                        object value = enumerator.Value;

                        if (key.EndsWith(".Text"))
                        {
                            // Find the value in source translation
                            string translation = Translate(destTranslation, value.ToString());

                            writer.AddResource(key, translation);
                        }
                        else
                        {
                            writer.AddResource(key, value);
                        }
                    }
                }
                finally
                {
                    writer.Close();
                }
            }
            finally
            {
                resourceReader.Close();
            }
        }
    }
}